/* Copyright 2008 Bas van den Berg
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string>

#include "yaffut.h"
#include "myassert.h"
#include "TestSession.h"
#include "TestRoom.h"

#include "MudContainer.h"
#include "MudPlayer.h"
#include "MudItem.h"
#include "Global.h"
#include "TaskQueue.h"

using namespace std;
using namespace Chronos;


struct MudContainerTest : public MudContainer {
public:
    MudContainerTest()
		: MudContainer("name", "descr")
		, item1(new MudItem(0,"item1", "", 1))
		, item2(new MudItem(0, "item2", "", 1))
		, item3(new MudItem(0, "item3", "", 1))
	{}
	virtual ~MudContainerTest() {
		if (!findItem("item1")) delete item1;
		if (!findItem("item2")) delete item2;
		if (!findItem("item3")) delete item3;
	}

	MudItem* item1;
	MudItem* item2;
	MudItem* item3;
};


TEST(MudContainerTest, testDescription) {
	ASSERT_STR_EQUAL("descr It's empty.", getDescription());

	addItem(item1);
	addItem(item2);
	ASSERT_STR_EQUAL("descr It contains:\n  item1\n  item2", getDescription());

	removeItem(item1);
	removeItem(item2);
	ASSERT_STR_EQUAL("descr It's empty.", getDescription());
}


TEST(MudContainerTest, testRemovingWithIterator) {
	addItem(item1);
	addItem(item2);
	addItem(item3);

	MudContainer::Items items2 = getItems();
	MudContainer::ItemsIter iter = items2.begin();
	while (iter != items2.end()) {
		removeItem(*iter);
		++iter;
	}
	ASSERT_EQUAL(3, items2.size());
	ASSERT_EQUAL(0, items.size());
}


struct MudOpenableContainerTest : public MudOpenableContainer {
public:
    MudOpenableContainerTest()
		: MudOpenableContainer("chest", "descr", 1)
		, taskQueue(0)
		, room1("room1")
        , session("player")
        , player(session.getPlayer())
		, item1(new MudItem(0, "item1", "", 1))
	{
        Global<TaskQueue>::set(&taskQueue);
		room1.addPlayer(player, "");
		session.clear();
    }
    ~MudOpenableContainerTest() {
		room1.removePlayer(player, "");
	}
	TaskQueue taskQueue;
	TestRoom room1;
	TestSession session;
	MudPlayer& player;
	MudItem* item1;
};


TEST(MudOpenableContainerTest, testOpen) {
    ASSERT_FALSE(isOpen);
    open(player);
	session.SESSION_CHECKWRITTEN("OK\n");
	room1.ROOM_CHECKWRITTEN("player opens the chest.\n");
    ASSERT_TRUE(isOpen);

    open(player);
	session.SESSION_CHECKWRITTEN("The chest is already open.\n");
	room1.ROOM_CHECKWRITTEN("");
}


TEST(MudOpenableContainerTest, testClose) {
    ASSERT_FALSE(isOpen);
    close(player);
	session.SESSION_CHECKWRITTEN("The chest is already closed.\n");
	room1.ROOM_CHECKWRITTEN("");
    ASSERT_FALSE(isOpen);

    open(player);
    session.clear();
    room1.clear();
    ASSERT_TRUE(isOpen);

    close(player);
	session.SESSION_CHECKWRITTEN("OK\n");
	room1.ROOM_CHECKWRITTEN("player closes the chest.\n");
    ASSERT_FALSE(isOpen);
}


TEST(MudOpenableContainerTest, testDescriptionGeneration) {
	ASSERT_STR_EQUAL("descr It's closed.", getDescription());
    open(player);
	ASSERT_STR_EQUAL("descr It's empty.", getDescription());
	addItem(item1);
	ASSERT_STR_EQUAL("descr It contains:\n  item1", getDescription());
    close(player);
	ASSERT_STR_EQUAL("descr It's closed.", getDescription());
}


